package org.anonymous.dobrochan.sqlite;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;

import org.anonymous.dobrochan.ApiWrapper;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.os.Build;

public class ImageCacheOpenHelper extends SQLiteOpenHelper implements IImageCache {
    private static final int DATABASE_VERSION = 1;
    private static final String TABLE_NAME = "images";
    private static final String KEY_COLUMN = "url";
    private static final String DATA_COLUMN = "data";
    private static final String[] GET_COLUMNS = { DATA_COLUMN };
    private static final String[] CHECK_COLUMNS = { KEY_COLUMN };
    private static final String TABLE_CREATE =
                "CREATE TABLE " + TABLE_NAME + " (" +
                KEY_COLUMN + " TEXT, " +
                DATA_COLUMN + " BLOB);";
    private SQLiteDatabase db;

    public ImageCacheOpenHelper(Context context) {
        super(context,
        		(Build.VERSION.SDK_INT>7?ApiWrapper.getExternalCacheDir(context).getAbsolutePath()+
                		"/":"")+"images_cache.sqlite",
        		null, 
        		DATABASE_VERSION);
		db = getWritableDatabase();
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL(TABLE_CREATE);
    }

	@Override
	public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
		db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME);
        onCreate(db);
	}
	
	/* (non-Javadoc)
	 * @see org.anonymous.dobrochan.sqlite.IImageCache#addImage(java.lang.String, java.io.InputStream)
	 */
	@Override
	public byte[] addImage(String uri, InputStream stream) {
//		db = getWritableDatabase();
		byte[] data = null;
        ContentValues cv = new ContentValues();
        cv.put(KEY_COLUMN, uri);
        try{
        	data = readBytesAndClose(stream);
        	cv.put(DATA_COLUMN, data);
        	db.insert(TABLE_NAME, null, cv);
        } catch (IOException e) {
        	e.printStackTrace();
        }
        return data;
	}
	
	/* (non-Javadoc)
	 * @see org.anonymous.dobrochan.sqlite.IImageCache#checkImage(java.lang.String)
	 */
	@Override
	public boolean checkImage(String uri) {
		Cursor c = db.query(TABLE_NAME,
				CHECK_COLUMNS,
				KEY_COLUMN+" = '"+uri.replace("'", "''")+"'",
				null,
				null,
				null,
				null,
				"1");
		boolean result = c.moveToFirst();
		c.close();
		return result;
	}
	
	/* (non-Javadoc)
	 * @see org.anonymous.dobrochan.sqlite.IImageCache#getImageData(java.lang.String)
	 */
	@Override
	public byte[] getImageData(String uri) {
		Cursor c = db.query(TABLE_NAME,
				GET_COLUMNS,
				KEY_COLUMN+" = '"+uri.replace("'", "''")+"'",
				null,
				null,
				null,
				null,
				"1");
		if(!c.moveToFirst()) {
			c.close();
			return null;
		}
		byte[] data = c.getBlob(0);
		c.close();
		return data;
	}
	
	/* (non-Javadoc)
	 * @see org.anonymous.dobrochan.sqlite.IImageCache#clearCache()
	 */
	@Override
	public void clearCache() {
		try {
			//db.delete(TABLE_NAME, "1", null);
			onUpgrade(db, DATABASE_VERSION, DATABASE_VERSION);
		} catch (Exception e) {
			//???
		}
	}
	
	public static byte[] readBytesAndClose(InputStream in) throws IOException {
	    try {
	        int block = 4 * 1024;
	        final ByteArrayOutputStream out = new ByteArrayOutputStream(block);
	        byte[] buff = new byte[block];
	        while (true) {
	            int len = in.read(buff, 0, block);
	            if (len < 0) {
	                break;
	            }
	            out.write(buff, 0, len);
	        }
	        return out.toByteArray();
	    } finally {
	        in.close();
	    }
	}

	@Override
	public boolean isFake() {
		return false;
	}
}
